using System;

namespace SharpMud.LPC
{
	public class MappingEntry : LPC.Object
	{
		private LPC.String _Key;
		private LPC.Object _Value;

		public MappingEntry()
		{
			_Key = new LPC.String();
			_Value = null;
		}

        private MappingEntry(LPC.String key, LPC.Object value)
        {
            _Key = key;
            _Value = value;
        }

		public MappingEntry(string key, LPC.Object value)
		{
			if(key==null || key.Length==0) throw new ArgumentNullException("key");
			if(value==null) throw new ArgumentNullException("value");

			_Key = new String(key);
			_Value = value;
		}

		public MappingEntry(string key, LPC.Array subArray)
			:this(key, (LPC.Object)subArray)
		{
		}

		public MappingEntry(string key, Mapping subMapping)
			:this(key, (LPC.Object)subMapping)
		{
		}

		public MappingEntry(string key, LPC.Integer value)
			:this(key, (LPC.Object)value)
		{
		}

		public MappingEntry(string key, LPC.Object[] subArray)
			:this(key, (LPC.Object)(new LPC.Array(subArray)))
		{
		}

		public MappingEntry(string key, int value)
			:this(key, (LPC.Object)(new LPC.Integer(value)))
		{
		}

		

		public string Key
		{
			get
			{
				return (string)_Key.Value;
			}
			set
			{
				_Key.Value = value;
			}
		}

		public LPC.Object Value
		{
			get
			{
				return _Value;				
			}
			set
			{
				_Value = value;
			}
		}

        public static bool TryParse(char[] text, ref int index, out LPC.Object result)
        {
            int i2 = index;
            result = null;
            
            LPC.Object o_key;
            bool keyParseSuccess = LPC.String.TryParse(text, ref i2, out o_key);
            LPC.String key = o_key as LPC.String;
            
            i2++;
            if (!(i2 < text.Length))
                return false;
            while(Char.IsWhiteSpace(text[i2]))
            { i2++; }
            if (text[i2] != ':')
                return false;

            LPC.Object[] objectRes = LPC.Object.Parse(text, ref i2, 1);
            if (objectRes.Length < 1)
                throw new InvalidLpcFormatException();
            LPC.Object value = objectRes[0];

            LPC.MappingEntry resultMappingEntry = new MappingEntry(key,value);
            result = resultMappingEntry;

            return true;
        }

		public override string ToParsableString()
		{
			if(_Value==null || _Key==null) throw new InvalidOperationException("The Mapping Entry must be fully initialized before it can be expressed as a string.");
            if (_Key.Value == null) throw new InvalidOperationException("The Mapping Entry must be fully initialized before it can be expressed as a string.");
            if (_Key.Value == string.Empty) throw new InvalidOperationException("The Mapping Entry must be fully initialized before it can be expressed as a string.");
			return _Key.ToParsableString() + ":" + _Value.ToParsableString();
		}

        protected override LPC.Object Clone()
        {
            return new MappingEntry((string)((ICloneable)this._Key).Clone(), (LPC.Object)((ICloneable)this._Value).Clone());
        }
	}
}
